package com.sven.transaction;

import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.messaging.Message;

/**
 * @RocketMQTransactionListener注解接收本地事务的监听
 * txProducerGroup 事务组名称（生产者分组）
 */
@RocketMQTransactionListener(txProducerGroup = "demo-group")
public class TransactionMsgListener implements RocketMQLocalTransactionListener {

    /**
     * 执行本地事务，在消息发送成功（预提交）会回调执行，
     * 一旦事务提交成功，下游应用的Consumer能收到该消息
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) {
        try {
            //获取前面生成的事务id
            String transactionId = (String) message.getHeaders().get(RocketMQHeaders.TRANSACTION_ID);
            //以事务id主键，执行本地事务
            String st =  new String((byte[]) message.getPayload());
            boolean result = saveOrder(st, transactionId);
            System.out.println("===========TransactionMsgListener-executeLocalTransaction===saveOrder===" + result);
            return result ? RocketMQLocalTransactionState.COMMIT : RocketMQLocalTransactionState.ROLLBACK;
            // return result ? RocketMQLocalTransactionState.COMMIT : RocketMQLocalTransactionState.UNKNOWN;
        }catch (Exception e){
            System.out.println("===========TransactionMsgListener-executeLocalTransaction===Exception===" + e);
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }

    public boolean saveOrder(String st, String transactionId){
        //将事务id设置为唯一主键
        //调用数据库insert into 订单表
        System.out.println("===========TransactionMsgListener-saveOrderr===message===" + st);
        System.out.println("===========TransactionMsgListener-saveOrder===transactionId===" + transactionId);
        return "你好".equals(st) ? true:false;
    }


    /**
     * 检查本地事务执行状况，如果executeLocalTransaction方法中返回的状态是未知UNKNOWN或者未返回状态，
     * 我默认会在预处理发送的1分钟后由Broker通知Producer检查本地事务,在Producer中回调本地事务监听器中的checkLocalTransaction方法
     */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        //获取事务id
        String transactionId = (String) message.getHeaders().get(RocketMQHeaders.TRANSACTION_ID);
        //以事务id为主键，查询本地事务执行情况
        if(isSuccess(transactionId)){
            return RocketMQLocalTransactionState.COMMIT;
        }
        return RocketMQLocalTransactionState.ROLLBACK;
    }

    public boolean isSuccess(String transactionId){
        //查询数据库select from 订单表
        System.out.println("===========TransactionMsgListener-isSuccess===transactionId===" + transactionId);
        return true;
    }

}
